using System;
using System.Diagnostics;
using System.Reflection;
using System.Resources;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;

namespace Microsoft.Samples.BizTalk.Adapter.Tcp.Setup.CustomActions
{
    /// <summary>
    ///     This class implements an installer class that deploys a BizTalk Assembly.
    /// </summary>
    /// <author>
    ///     Paul Brown
    /// </author>
    [RunInstaller(true)]
    public partial class DeployBizTalkAssembly : Installer
    {
        #region Private Constants

        private const string ApplicationName = "BizTalk.Samples.Adapter.Tcp";

        #endregion

        #region Private Instance Members

        private ResourceManager _resMgr;    // Resource manager used to access assembly resources

        #endregion

        #region Constructor

        /// <summary>
        ///     This is the default constructor for the class.
        /// </summary>
        public DeployBizTalkAssembly()
        {
            InitializeComponent();

            // Initialize resource manager
            this._resMgr = new ResourceManager(ResourceConstants.BaseName, Assembly.GetExecutingAssembly());
        }

        #endregion

        #region Public Instance Methods

        /// <summary>
        ///     This method is called by the Installer when this custom action is being installed.
        /// </summary>
        public override void Install(System.Collections.IDictionary stateSaver)
        {
            // Call base implementation
            base.Install(stateSaver);

            /// Code added by Koushal to Deploy dotnet assemblies
            /// Either dotnet assembly will be deployed or BizTalk assembly
            /// Get custom action parameters
            string dotnetassembly1 = this.Context.Parameters["dotnetassembly1"];
            string dotnetassembly2 = this.Context.Parameters["dotnetassembly2"];
            string assembly = this.Context.Parameters["assembly"];
            string btsDeployTool = this.Context.Parameters["btstool"];

            // Get custom action parameters
            if (string.IsNullOrEmpty(assembly))
            {
                throw new ArgumentNullException("assembly", this._resMgr.GetString(ResourceConstants.MustSpecifyAssemblyToDeploy));
            }

            if (string.IsNullOrEmpty(dotnetassembly2))
            {
                throw new ArgumentNullException("dotnetassembly2", this._resMgr.GetString(ResourceConstants.MustSpecifyAssemblyToDeploy));
            }

            if (string.IsNullOrEmpty(dotnetassembly1))
            {
                throw new ArgumentNullException("dotnetassembly1", this._resMgr.GetString(ResourceConstants.MustSpecifyAssemblyToDeploy));
            }

            if (string.IsNullOrEmpty(btsDeployTool))
            {
                throw new ArgumentNullException("btstool", this._resMgr.GetString(ResourceConstants.MustSpecifyBtsToolFilePath));
            }

            //
            // Create BizTalk Application
            //

            // Set process start information
            ProcessStartInfo processStartInfo = new ProcessStartInfo(btsDeployTool);
            processStartInfo.Arguments = "AddApp /ApplicationName:" + DeployBizTalkAssembly.ApplicationName;
            processStartInfo.RedirectStandardOutput = true;
            processStartInfo.UseShellExecute = false;
            processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            // Invoke BTSTask executable
            Process process = new Process();
            process.StartInfo = processStartInfo;
            process.Start();
            process.WaitForExit();
            process.Close();

            //
            // Add Resource
            //

            // Modify process start information
            processStartInfo.Arguments = "AddResource /ApplicationName:BizTalk.Samples.Adapter.Tcp /Type:System.BizTalk:Assembly /Options:GacOnInstall,GacOnImport /Overwrite /Source:\"" + dotnetassembly1 + "\"";

            // Invoke BTSTask executable
            process = new Process();
            process.StartInfo = processStartInfo;
            process.Start();

            // Wait for process to finish (tool writes errors out to standard output!)
            string error = process.StandardOutput.ReadToEnd();
            process.WaitForExit();

            if (process.ExitCode != 0)
            {
                throw new Exception(string.Format(this._resMgr.GetString(ResourceConstants.BtsDeploymentFailed), process.ExitCode, error));
            }

            // Cleanup
            process.Close();

            /// Deploy Dotnetassemblies
            /// 

            processStartInfo.Arguments = "AddResource /ApplicationName:BizTalk.Samples.Adapter.Tcp /Type:System.BizTalk:Assembly /Options:GacOnInstall,GacOnImport /Overwrite /Source:\"" + dotnetassembly2 + "\"";

            // Invoke BTSTask executable
            process = new Process();
            process.StartInfo = processStartInfo;
            process.Start();

            // Wait for process to finish (tool writes errors out to standard output!)
            error = process.StandardOutput.ReadToEnd();
            process.WaitForExit();

            if (process.ExitCode != 0)
            {
                throw new Exception(string.Format(this._resMgr.GetString(ResourceConstants.BtsDeploymentFailed), process.ExitCode, error));
            }

            // Cleanup
            process.Close();

            /*----------------------------------------------------------------*/

            processStartInfo.Arguments = "AddResource /ApplicationName:BizTalk.Samples.Adapter.Tcp /Type:System.BizTalk:BizTalkAssembly /Overwrite /Source:\"" + assembly + "\"";

            // Invoke BTSTask executable
            process = new Process();
            process.StartInfo = processStartInfo;
            process.Start();

            // Wait for process to finish (tool writes errors out to standard output!)
            error = process.StandardOutput.ReadToEnd();
            process.WaitForExit();

            if (process.ExitCode != 0)
            {
                throw new Exception(string.Format(this._resMgr.GetString(ResourceConstants.BtsDeploymentFailed), process.ExitCode, error));
            }

            // Cleanup
            process.Close();

        }

        #endregion
    }
}